package com.heatingcharge.service.sys.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heatingcharge.common.exception.BaseException;
import com.heatingcharge.common.util.BeanValidator;
import com.heatingcharge.common.util.LevelUtil;
import com.heatingcharge.common.util.ResponseCodeEnum;
import com.heatingcharge.entity.sys.SysDept;
import com.heatingcharge.mapper.sys.SysDeptMapper;
import com.heatingcharge.param.DeptParam;
import com.heatingcharge.security.JwtUser;
import com.heatingcharge.security.util.SecurityUtil;
import com.heatingcharge.service.sys.ISysDeptService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *   服务实现类
 * </p>
 *
 * @author devin.jiang
 * @since 2019-06-27
 */
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {

    @Override
    public List<SysDept> selectDepts() {
        return baseMapper.selectDepts();
    }

    @Override
    public Integer save(DeptParam deptParam) {
        //校验字段合法性
        BeanValidator.check(deptParam);
        //检验部门是否已经存在
        if (checkExist(deptParam.getParentId(),deptParam.getName(),null)){
            //部门已经存在
            throw new BaseException(ResponseCodeEnum.DEPT_EXIST.getMessage(),ResponseCodeEnum.DEPT_EXIST.getCode());
        }

        SysDept sysDept=SysDept.builder()
                .name(deptParam.getName())
                .parentId(deptParam.getParentId())
                .seq(deptParam.getSeq())
                .remark(deptParam.getRemark())
                .build();
        sysDept.setLevel(LevelUtil.calculateLevel(getLevel(deptParam.getParentId()),deptParam.getParentId()));
        JwtUser user = SecurityUtil.getUser();
        sysDept.setCreatedBy(user.getRealName());
        return baseMapper.insert(sysDept);
    }

    @Override
    public Integer update(DeptParam deptParam) {
        //校验字段合法性
        BeanValidator.check(deptParam);
        //检验部门是否已经存在
        if (checkExist(deptParam.getParentId(),deptParam.getName(),deptParam.getId())){
            //部门已经存在
            throw new BaseException(ResponseCodeEnum.DEPT_EXIST.getMessage(),ResponseCodeEnum.DEPT_EXIST.getCode());
        }
        SysDept before=this.getById(deptParam.getId());
        if (ObjectUtil.isNull(before)){
            throw new BaseException(ResponseCodeEnum.DEPT_NON_EXIST.getMessage(),ResponseCodeEnum.DEPT_NON_EXIST.getCode());
        }
        SysDept after=new SysDept();
        BeanUtils.copyProperties(deptParam, after);

        after.setLevel(LevelUtil.calculateLevel(getLevel(deptParam.getParentId()),deptParam.getParentId()));
        JwtUser user = SecurityUtil.getUser();
        after.setUpdatedBy(user.getRealName());
        return baseMapper.updateById(after);
    }

    @Override
    public Boolean checkExist(Integer parentId, String deptName, Integer id) {
        QueryWrapper<SysDept> queryWrapper=new QueryWrapper<>();
        if (parentId!=null) {
            queryWrapper.eq("parent_id",parentId);
        }
        queryWrapper.eq("name",deptName);
        if (id!=null){
            queryWrapper.ne("id",id);
        }
        Collection<SysDept> sysDepts = this.list(queryWrapper);
        return sysDepts.size()>0;
    }

    private String getLevel(Integer deptId) {
        SysDept dept = this.getById(deptId);
        if (dept == null) {
            return null;
        }
        return dept.getLevel();
    }

    @Override
    public boolean removeById(Serializable id) {
        // 部门层级删除
        List<Integer> idList = this.list(Wrappers.<SysDept>query().lambda().eq(SysDept::getParentId, id)).stream().map(SysDept::getId).collect(Collectors.toList());
        //如果存在子部门  则不能删除
        if (idList.size()>0){
            throw new BaseException(ResponseCodeEnum.DEPT_HAS_CHILDREN.getMessage(),ResponseCodeEnum.DEPT_HAS_CHILDREN.getCode());
        }
        return super.removeById(id);
    }
}
